package VideoJuego;

import Acelerometro.Acelerometro;
import SistemaGeneral.TheRace;
import Sonido.Sonido;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import javax.microedition.rms.RecordStoreNotFoundException;
import javax.microedition.rms.RecordStoreNotOpenException;

/**
 *Desarrolladores:
 *Equipo: The Dream Team
 * @author Arturo Ramires Morales           A01165819
 * @author José Francisco Ruiz Martínez     A01161142
 * @author José Héctor Bermúdez Robles      A01166298
 * @version 1.0.3  Septiembre 2010
 * Esta clase se encarga de administrar todos los objetos que se necesitan en cada carrera
 * dibujandolos y actualizandolos en el orden adecuado
 */
public class Videojuego extends GameCanvas {
    // Todos los objetos que tendrá nuestro juego

    private Personaje personaje;
    private boolean pausado = false,freno=false;
    public boolean destruido = false;
    private Image pausa,ImagenFinal;
    /**
     * Ancho de la pantalla
     */
    public static int ANCHO;        // Ancho y alto de la pantalla del celular
    /**
     * Alto de la pantalla
     */
    public static int ALTO;
    /**
     * Opción de la acción que esta realizando el personaje
     */
    public int estadoPersonaje;
    /**
     * El animador es un Thread que corre en segundo plano
     */
    public AnimadorJuego animador;  // Estará avisando a cada rato que se actualice y dibuje
    private Graphics g;         // Contexto gráfico para hacer trazos
    // Es la referencia para detener la aplicación
    private TheRace midlet;
    private AdminNivel nivelJuego;
    private int contadorBasuras = 0,seleccionarPersonaje=1, nivel=1;
    private Reloj reloj;
    private Acelerometro acelerometro;
    private int ySensor=0;
    private Marcador marcador;
    private int contador=0;
    private boolean botonApretado,salir=false,nivelFinal=false;
    private Boton boton;
    private int posicionPresionadaX, posicionPresionadaY,contadorArma=0;
    private boolean botonPresionado,destruidoArma=false,nivelCompleto=false;
    private Sonido jump,musica;
    private RecordStore HigHScore;
    private Image next,menuJuego;
    private RecordStore juegoGuardado;


    /**
     *Crea el videojuego y todos los objetos necesarios para poder dibujar el circuito y
     * el personaje
     * @param midlet
     */
    public Videojuego(TheRace midlet, Acelerometro acelerometro,int seleccionarPersonaje,int nivel) {

        super(true);
        this.midlet = midlet;
        this.setFullScreenMode(true);
        this.ANCHO = this.getWidth();
        this.ALTO = this.getHeight();
        this.seleccionarPersonaje=seleccionarPersonaje;
        this.acelerometro = acelerometro;
        this.nivel=nivel;
        System.out.println("Ancho: " + ANCHO);
        System.out.println("Alto: " + ALTO);

        try {
            HigHScore.openRecordStore("Puntajes Altos", true);
            midlet.juegoGuardado.openRecordStore("juegoGuardado", true);
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }

        g = this.getGraphics();

        try {
            nivelJuego = new AdminNivel(midlet,nivel, ANCHO, ALTO);
            pausa = Image.createImage("/ImagenesMenu/pausa.png");
            next = Image.createImage("/ImagenesJuego/next.png");
            menuJuego = Image.createImage("/ImagenesJuego/menuJuego.png");
            personaje = new Personaje(1, getHeight() / 2, "/ImagenesJuego/personaje" + seleccionarPersonaje + ".png");
            estadoPersonaje = 3;
            reloj = new Reloj(0, ANCHO, ALTO);
            marcador = new Marcador(this, ANCHO, ALTO);
            boton = new Boton();
            if(midlet.isSonido()==true){
            jump = new Sonido ("/Sonido/jump.mp3");
            musica = new Sonido ("/Sonido/musicafondo.mp3");
            musica.iniciarReproductor();
            }
            botonApretado = false;

                  // Ultimas líneas que inician la animación
            animador = new AnimadorJuego(this);
        } catch (IOException ex) {
            System.out.println("No se pueden cargar los fondos");
        }
        
    }

    /*
     * Método que se encarga de actualizar el estado de los elementos a lo larfo de la
     * carrera
     */
    void actualizar() {
       if((reloj.getTiempo())>= 179) {
          nivelCompleto=true;
          nivelFinal=true;
            try {
                ImagenFinal = Image.createImage("/ImagenesJuego/final.png");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
       }
       if(salir==true){
//////           guardarJuego();
           contadorBasuras = 0;
           destruido = true;
           this.destruir();
           midlet.setNivel(this.nivel);
           midlet.setDisplayactual(1);
           midlet.startApp();
       }else  if(reloj.getTiempo()>= 180) {
//////            agregarPuntaje();
            contadorBasuras = 0;
            destruido = true;
            this.destruir();
            if(this.nivel ==3){
////////            agregarPuntaje();
            midlet.setNivel(1);
            midlet.setDisplayactual(1);
            midlet.startApp();

            }else{
            midlet.setNivel(nivel + 1);
            midlet.setDisplayactual(2);
            midlet.startApp();
            }
            
    } else {

            // Leer el teclado
            int teclado = getKeyStates(); // Se lee el patrón de bits que indican el estado actual del teclado
            ySensor = this.acelerometro.getySensor();
            if (!pausado) {
                if(freno==true){
                    reloj.incrementar(animador.RETARDO);
                    freno=false;
                    this.estadoDelBoton();
                }else{
                moverPersonaje(teclado, ySensor);
                this.estadoDelBoton();
                personaje.actualizar(estadoPersonaje);
                nivelJuego.actualizar();
                marcador.incrementar();
                reloj.incrementar(animador.RETARDO);
                
                if(contadorArma>30){
                    contadorArma=0;
                 if(destruidoArma==true){
                  nivelJuego.crearArma();
                  destruidoArma=false;
                }}
                verficarChoque();
                contadorArma++;
                 if(midlet.isSonido()==true){
                musica.iniciarReproductor();
                }
                }
                
            }else{
                 this.estadoDelBoton();
                 musica.pararSonido();
            }

        }
    }
    /*
     * Dibuja cada uno de los elementos que tendrá el juego
     */

    void dibujar() {

        // Borra la pantalla
        g.setColor(0x000000);
        g.fillRect(0, 0, ANCHO, ALTO);
        if (!destruido) {
            //Se dibujan los objetos de al administrador de nivel(pista, las basuras, armas)
            nivelJuego.dibujar(g);
            personaje.dibujar(g);
            reloj.dibujar(g);
            marcador.dibujarPuntaje(g);
            boton.dibujar(g);
            if(nivelCompleto == true){
                 g.drawImage(next, ANCHO / 2, ALTO / 2, Graphics.VCENTER | Graphics.HCENTER);
                }
            if(nivelFinal==true){
                g.drawImage(ImagenFinal, ANCHO / 2, ALTO / 2, Graphics.VCENTER | Graphics.HCENTER);
            }
           if (pausado) {
                g.drawImage(pausa, ANCHO / 2, ALTO / 2, Graphics.VCENTER | Graphics.HCENTER);
                g.drawImage(menuJuego, ANCHO / 2, ALTO / 2, Graphics.VCENTER | Graphics.HCENTER);
                boton.getBotonPausa().paint(g);
            }
        }
        flushGraphics();    // Actualiza los cambios en la memoria de la pantalla
    }

    /*
     * Mueve y actualiza al personaje dependiendo de como se mueva el celular.
     * Este efecto funciona con el acelerómetro
     */
    private void moverPersonaje(int teclado, int ySensor) {
        if (ySensor <= -4) {
            estadoPersonaje = 1;
            personaje.actualizar(estadoPersonaje);
        }
        if (ySensor > 4) {
            estadoPersonaje = 2;
            personaje.actualizar(estadoPersonaje);
        }
        if ((ySensor > -4 && ySensor < 4)) {
            estadoPersonaje = 3;
        }
    }
    /*
     * Verifica si hay un choque entre el personaje y la basura. Si lo hay se destruye la basura
     * y se crea una nueva
     */

    void verficarChoque() {
        if(nivelJuego.getBasura().getRefPixelX()<=10){
        if (personaje.collidesWith(nivelJuego.getBasura(), true)) {
            contadorBasuras++;
            contador = contador + nivelJuego.getValorBasura();
            nivelJuego.getBasura().setVisible(false);
            nivelJuego.destruirBasura();
            nivelJuego.crearBasura();
        }
         if (nivelJuego.getBasura().getRefPixelX() < 0) {
            nivelJuego.getBasura().setVisible(false);
            nivelJuego.destruirBasura();
            nivelJuego.crearBasura();
        }
        }


        if(destruidoArma==false){
        if (nivelJuego.getArma().getRefPixelX() < 0) {
            nivelJuego.getArma().setVisible(false);
            nivelJuego.destruirArma();
            nivelJuego.crearArma();
            destruidoArma=false;
        }
        if (personaje.collidesWith(nivelJuego.getArma(), true)) {
            if(nivelJuego.getArma().getRefPixelX()<=10){
            if((contador >30)&&(estadoPersonaje != 4)){
            contador = contador + nivelJuego.getValorArma();
            }
            nivelJuego.getArma().setVisible(false);
            nivelJuego.destruirArma();
            destruidoArma=true;
            if(midlet.isVibrar()==true){
            midlet.vibrar(200);
            }
        }
        }
        }

        if (nivelJuego.getArboles().getRefPixelX() < 0) {
            nivelJuego.getArboles().setVisible(false);
            nivelJuego.destruirArbol();
            nivelJuego.crearArbol();
        }
    }

    /**
     *Manda todos los objetos del videojuego a destruirse
     */
    public void destruir() {
        this.nivelJuego.destruir();
        this.animador.terminar();
        this.marcador.destruir();
        this.reloj.destruir();
        this.personaje.destruir();
         if(midlet.isSonido()==true){
        musica.pararSonido();
        musica.terminate();
        jump.pararSonido();
        jump.terminate();
        }
        next=null;
        animador = null;
        nivelJuego = null;
        personaje = null;
        pausado = false;
        pausa = null;
        estadoPersonaje = 0;
        contadorBasuras = 0;
        reloj = null;
        ySensor = 0;
        marcador = null;
        musica=null;
        jump=null;
        contador = 0;
        menuJuego=null;
    }

    int getContadorBasura() {
        return contador;
    }

    public void estadoDelBoton() {
        if(pausado != true){
        if (this.botonPresionado) {
            if ((this.posicionPresionadaX >= 60 && this.posicionPresionadaX <= 120) && ((this.posicionPresionadaY <= (boton.getBotonFreno().getY()+boton.getBotonFreno().getWidth()) && this.posicionPresionadaY >= (boton.getBotonFreno().getY()- boton.getBotonFreno().getWidth())))) {
                boton.getBotonFreno().setFrame(1);
                freno=!freno;
            } else if ((this.posicionPresionadaX >= 0 && this.posicionPresionadaX <= 60) && (this.posicionPresionadaY <= (boton.getBotonSalto().getY()+boton.getBotonSalto().getWidth()) && this.posicionPresionadaY >= (boton.getBotonSalto().getY()- boton.getBotonSalto().getWidth()))) {
                boton.getBotonSalto().setFrame(1);
                estadoPersonaje = 4;
                 if(midlet.isSonido()==true){
                jump.iniciarReproductor();
                }
                ySensor=0;
            } else if ((this.posicionPresionadaX >= 0 && this.posicionPresionadaX <= 50) && (this.posicionPresionadaY <= 50 && this.posicionPresionadaY >= 0)) {
                boton.getBotonPausa().setFrame(1);
                pausado= !pausado;
                botonPresionado=false;
            }
        } else {
            boton.getBotonFreno().setFrame(0);
            boton.getBotonSalto().setFrame(0);
            boton.getBotonPausa().setFrame(0);
        }
        }else{
        if ((this.posicionPresionadaX >= ((ANCHO/2)+10) && this.posicionPresionadaX <= ((ANCHO/2)+ menuJuego.getWidth())) && (this.posicionPresionadaY <= ((ALTO/2)+(menuJuego.getHeight()/2)) && this.posicionPresionadaY >= ((ALTO/2)-(menuJuego.getHeight()/2)))) {
                pausado= !pausado;
                botonPresionado=false;
        }else if ((this.posicionPresionadaX >= ((ANCHO/2)- menuJuego.getWidth())) && this.posicionPresionadaX <= ((ANCHO/2)-10) && (this.posicionPresionadaY <= ((ALTO/2)+(menuJuego.getHeight()/2)) && this.posicionPresionadaY >= ((ALTO/2)-(menuJuego.getHeight()/2)))) {
                salir=true;
                }
        }
    }

     protected void pointerPressed(int x, int y) {
        this.botonPresionado = true;
        this.posicionPresionadaX = x;
        this.posicionPresionadaY = y;
    }

    protected void pointerReleased(int x, int y) {
        this.botonPresionado = false;
    }

    protected void hideNotify (){
        pausado = true;
    }
    protected void showNotify(){       
    }
    private void agregarPuntaje(){
          int puntaje = marcador.getMarcador();
          byte [] data = Integer.toString(puntaje).getBytes();
          try{
              HigHScore.addRecord(data, 0, data.length);
          }catch(RecordStoreException ex){
              ex.printStackTrace();
          }
        try {
            HigHScore.closeRecordStore();
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    private void guardarJuego (){
        int nivela = (midlet.getMarcadorActual()*100)+(midlet.getNivel()*10) + midlet.getTipoDpersonaje();
          byte [] data = Integer.toString(nivela).getBytes();
          try{
              midlet.juegoGuardado.addRecord(data, 0, data.length);
          }catch(RecordStoreException ex){
              ex.printStackTrace();
          }
        try {
            midlet.juegoGuardado.closeRecordStore();
        } catch (RecordStoreNotOpenException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }
}
